<template>
  <view class="qiun-data-charts" :style="{height: canvasHeight}">
    <!-- 显示加载状态 -->
    <view class="qiun-loading" v-if="loading">
      <view class="qiun-loading-icon"></view>
      <view class="qiun-loading-text">{{loadingText}}</view>
    </view>
    
    <!-- 无数据提示 -->
    <view class="qiun-empty" v-if="!loading && (!chartData || !chartData.series || chartData.series.length === 0)">
      <view class="qiun-empty-text">{{emptyText}}</view>
    </view>
    
    <!-- 图表画布区域 -->
    <canvas 
      class="qiun-charts-canvas" 
      :canvas-id="canvasId" 
      :id="canvasId" 
      @touchstart="touchStart" 
      @touchmove="touchMove" 
      @touchend="touchEnd"
    ></canvas>
  </view>
</template>

<script>
import { ref, onMounted, watch, getCurrentInstance } from 'vue';
import uCharts from './u-charts.js';
import { deepCopyObject } from './u-charts-tools.js';

export default {
  name: 'QiunDataCharts',
  props: {
    // 图表类型：柱状图column、折线图line、饼图pie等
    type: {
      type: String,
      default: 'column'
    },
    // 图表数据：包含categories分类和series系列数据
    chartData: {
      type: Object,
      default: () => ({
        categories: [],
        series: []
      })
    },
    // 是否显示加载中
    loading: {
      type: Boolean,
      default: false
    },
    // 画布ID
    canvasId: {
      type: String,
      default: 'qiun-chart'
    },
    // 画布高度
    canvasHeight: {
      type: String,
      default: '300px'
    },
    // 画布背景色
    background: {
      type: String,
      default: '#FFFFFF'
    },
    // 是否开启图表缩放功能
    enableScroll: {
      type: Boolean,
      default: false
    },
    // 图表配置项
    chartOpts: {
      type: Object,
      default: () => ({})
    }
  },
  
  setup(props, context) {
    // 响应式数据
    const chartInstance = ref(null);    // 图表实例
    const isFirst = ref(true);          // 是否首次渲染
    const loadingText = ref('数据加载中...');  // 加载提示文本
    const emptyText = ref('暂无数据');        // 空数据提示文本
    const currentCanvas = ref(null);     // 当前画布对象
    const inited = ref(false);          // 是否已初始化
    
    const instance = getCurrentInstance(); // 获取组件实例
    
    /**
     * 初始化图表
     * 根据传入的图表类型和数据创建图表实例
     */
    const initChart = () => {
      // 如果没有数据，不绘制图表
      if (!props.chartData || !props.chartData.series || props.chartData.series.length === 0) {
        return;
      }
      
      // 获取画布上下文
      uni.createSelectorQuery()
        .in(instance)
        .select('#' + props.canvasId)
        .boundingClientRect(data => {
          if (!data) {
            console.error('获取不到画布ID为：' + props.canvasId + '的组件信息，请确认');
            return;
          }
          
          // 获取画布对象
          const ctx = uni.createCanvasContext(props.canvasId, instance);
          currentCanvas.value = ctx;
          
          // 图表基础配置
          const defaultOpts = {
            type: props.type,                  // 图表类型
            context: ctx,                      // 画布上下文
            width: data.width,                 // 画布宽度
            height: data.height,               // 画布高度
            categories: props.chartData.categories || [], // 分类数据
            series: props.chartData.series || [],        // 系列数据
            animation: true,                   // 是否开启动画
            background: props.background,      // 背景色
            padding: [15, 15, 15, 15],         // 图表边距
            enableScroll: props.enableScroll,  // 是否可缩放
            legend: {                          // 图例配置
              show: true,
              position: 'bottom',
              float: 'center',
              padding: 5,
              margin: 5
            },
            xAxis: {                           // X轴配置
              disableGrid: false,
              gridType: 'dash',
              dashLength: 4,
              scrollShow: true,
              fontColor: '#666666',
              boundaryGap: 'center'
            }, 
            yAxis: {                           // Y轴配置
              gridType: 'dash',
              dashLength: 4,
              splitNumber: 5,
              format: val => val,
              min: 0
            },
            extra: {                           // 额外配置
              column: {
                width: 30,
                barBorderRadius: 0
              },
              line: {
                width: 2,
                activeType: 'hollow'
              },
              pie: {
                activeRadius: 10,
                offsetAngle: 0,
                labelWidth: 15,
                border: false,
                borderWidth: 3,
                borderColor: '#FFFFFF'
              },
              ring: {
                ringWidth: 30,
                centerColor: '#FFFFFF',
                activeRadius: 10,
                offsetAngle: 0,
                labelWidth: 15
              }
            }
          };
          
          // 合并用户自定义配置
          const opts = Object.assign({}, defaultOpts, props.chartOpts || {});
          
          // 创建图表实例
          chartInstance.value = new uCharts(opts);
          
          // 首次渲染结束
          isFirst.value = false;
          
          // 初始化完成事件
          inited.value = true;
          context.emit('inited', {
            width: data.width,
            height: data.height
          });
        })
        .exec();
    };
    
    /**
     * 更新图表数据
     * 当数据或配置变化时调用
     */
    const updateChart = () => {
      // 如果没有数据或图表实例未创建，不更新
      if (!props.chartData || !props.chartData.series || props.chartData.series.length === 0 || !chartInstance.value) {
        return;
      }
      
      // 更新数据并重绘
      chartInstance.value.updateData({
        categories: props.chartData.categories || [],
        series: props.chartData.series || []
      });
    };
    
    // 监听图表数据变化，自动更新图表
    watch(() => props.chartData, (newVal, oldVal) => {
      if (inited.value && chartInstance.value) {
        updateChart();
      } else if (!isFirst.value && !chartInstance.value) {
        // 之前图表实例被销毁，需要重新初始化
        initChart();
      } else if (isFirst.value) {
        // 首次渲染不做处理，等待组件挂载完成
      }
    }, { deep: true });
    
    // 监听图表类型变化，重新初始化图表
    watch(() => props.type, (newVal, oldVal) => {
      if (newVal !== oldVal) {
        chartInstance.value = null; // 清除旧实例
        initChart(); // 重新初始化
      }
    });
    
    // 触摸开始事件，用于图表交互
    const touchStart = (e) => {
      if (chartInstance.value && props.enableScroll) {
        chartInstance.value.touchStart(e);
      }
    };
    
    // 触摸移动事件，用于图表交互
    const touchMove = (e) => {
      if (chartInstance.value && props.enableScroll) {
        chartInstance.value.touchMove(e);
      }
    };
    
    // 触摸结束事件，用于图表交互
    const touchEnd = (e) => {
      if (chartInstance.value && props.enableScroll) {
        chartInstance.value.touchEnd(e);
      }
    };
    
    // 组件挂载完成后初始化图表
    onMounted(() => {
      // 延迟初始化，确保DOM已经渲染
      setTimeout(() => {
        initChart();
      }, 300);
    });
    
    // 导出方法和响应式数据
    return {
      chartInstance,
      loadingText,
      emptyText,
      touchStart,
      touchMove,
      touchEnd
    };
  }
};
</script>

<style lang="scss">
.qiun-data-charts {
  width: 100%;
  position: relative;
  
  /* 图表画布样式 */
  .qiun-charts-canvas {
    width: 100%;
    height: 100%;
  }
  
  /* 加载中样式 */
  .qiun-loading {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: rgba(255, 255, 255, 0.8);
    z-index: 9;
    
    .qiun-loading-icon {
      width: 40rpx;
      height: 40rpx;
      border: 4rpx solid #f3f3f3;
      border-top: 4rpx solid #3498db;
      border-radius: 50%;
      animation: qiun-loading-rotate 2s infinite linear;
    }
    
    .qiun-loading-text {
      margin-top: 20rpx;
      font-size: 26rpx;
      color: #999999;
    }
  }
  
  /* 无数据提示样式 */
  .qiun-empty {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #ffffff;
    z-index: 8;
    
    .qiun-empty-text {
      font-size: 26rpx;
      color: #999999;
      padding: 20rpx 0;
    }
  }
}

/* 加载动画关键帧 */
@keyframes qiun-loading-rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
